/*
 * Copyright 2012-2013 EZC Group S.A. RCS Luxembourg B140949
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.yobidrive.y3.http;

import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;

import com.yobidrive.y3.exceptions.Y3ErrorCode;

/**
 * Utility class to map HTTP status code and errorMessage
 * to an Y3ErrorCode value; 
 * 
 * @author david
 *
 */
public class HttpErrorCodeMapper {
	static private final Logger logger = Logger.getLogger(HttpErrorCodeMapper.class);
	/**
	 * Key   = HttpStatusCode-HttpReasonMessage
	 * Value = Y3ErrorCode
	 */
	private static Map<String,Integer> httpErrorCodeMapping = null;
	
	/**
	 * Add all the values inside the map, only called once
	 */
	private static void initMapIfRequired() {
		if ( httpErrorCodeMapping == null ) {
			httpErrorCodeMapping = new HashMap<String, Integer>();
			httpErrorCodeMapping.put(HttpStatus.SC_BAD_REQUEST+"-"+"BadDigest",Y3ErrorCode.ERRCODE_BAD_DIGEST);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"InvalidSecurity",Y3ErrorCode.ERRCODE_AUTHFAILED);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"NoToken",Y3ErrorCode.ERRCODE_AUTHFAILED_NO_TOKEN);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"NoUser",Y3ErrorCode.ERRCODE_AUTHFAILED_NO_USER);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"InvalidToken",Y3ErrorCode.ERRCODE_AUTHFAILED_INVALID_TOKEN);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"MismatchingUser",Y3ErrorCode.ERRCODE_AUTHFAILED_USER_MISMATCH);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"AccountBlocked",Y3ErrorCode.ERRCODE_AUTHFAILED_ACCOUNT_BLOCKED);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"MissingSafeSecret",Y3ErrorCode.ERRCODE_SAFE_SECRET_MISSING);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"InvalidSafeSecret",Y3ErrorCode.ERRCODE_SAFE_SECRET_INVALID);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"ExpiredSafeSecret",Y3ErrorCode.ERRCODE_SAFE_SECRET_EXPIRED);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"NoKeyAttached",Y3ErrorCode.ERRCODE_NO_KEYS_ATTACHED);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"InsufficientCredits",Y3ErrorCode.ERRCODE_INSUFFICIENT_CREDITS);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"Disallowed",Y3ErrorCode.ERRCODE_DISALLOWED);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"NoAccess",Y3ErrorCode.ERRCODE_NOACCESS);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"BadApiKey",Y3ErrorCode.ERRCODE_BAD_APIKEY);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"BadApiSign",Y3ErrorCode.ERRCODE_BAD_APISIGN);
			httpErrorCodeMapping.put(HttpStatus.SC_NOT_FOUND+"-"+"InvalidRequest",Y3ErrorCode.ERRCODE_INVALID_REQUEST);
			httpErrorCodeMapping.put(HttpStatus.SC_BAD_REQUEST+"-"+"AlreadyExists",Y3ErrorCode.ERRCODE_ALREADY_EXISTS);
			httpErrorCodeMapping.put(HttpStatus.SC_BAD_REQUEST+"-"+"NotEmpty",Y3ErrorCode.ERRCODE_NOT_EMPTY);
			httpErrorCodeMapping.put(HttpStatus.SC_BAD_REQUEST+"-"+"InvalidUri",Y3ErrorCode.ERRCODE_INVALID_URI);
			httpErrorCodeMapping.put(HttpStatus.SC_BAD_REQUEST+"-"+"InvalidParameter",Y3ErrorCode.ERRCODE_INVALID_PARAMETER);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"InvalidUsername",Y3ErrorCode.ERRCODE_INVALID_USERNAME);
			httpErrorCodeMapping.put(HttpStatus.SC_BAD_REQUEST+"-"+"DuplicateUsername",Y3ErrorCode.ERRCODE_DUPLICATE_USERNAME);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"AccountNotValidated",Y3ErrorCode.ERRCODE_USERNAME_NOT_VALIDATED);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"ExternalDomain",Y3ErrorCode.ERRCODE_EXTERNAL_DOMAIN);
			httpErrorCodeMapping.put(HttpStatus.SC_NOT_FOUND+"-"+"InvalidUid",Y3ErrorCode.ERRCODE_INVALID_UID);
			httpErrorCodeMapping.put(HttpStatus.SC_INTERNAL_SERVER_ERROR+"-"+"InternalError",Y3ErrorCode.ERRCODE_INTERNAL);
			httpErrorCodeMapping.put(HttpStatus.SC_INTERNAL_SERVER_ERROR+"-"+"",Y3ErrorCode.ERRCODE_INTERNAL);
			httpErrorCodeMapping.put(HttpStatus.SC_FORBIDDEN+"-"+"StrongAuthRequired",Y3ErrorCode.ERRCODE_STRONGAUTH_REQUIRED);

		}
	}
	
	public static int getY3ErrorCode(int httpStatusCode, String httpMessage) {
		initMapIfRequired();
		String key = httpStatusCode+"-"+(httpMessage==null?"":httpMessage);
		Integer mappedCode = httpErrorCodeMapping.get(key);
		if ( mappedCode == null ) {
			logger.error("[MISSING HTTPErrorCode-Y3Code Mapping for "+key);
			mappedCode = Y3ErrorCode.ERRCODE_INTERNAL;
		}
		return mappedCode;
	}
	
}
